-module(lib_misc).
-export([even/1, odd/1,for/3, qsort/1, pythag/1, perms/1, odds_and_evens1/1,
        odds_and_evens2/1, my_tuple_to_lists/1, for2/3, my_time_func/1]).

for2(I, Max, F) -> for(I, Max-1, F).

for(Max, Max, F) -> [F(Max)];
for(I, Max, F) -> [F(I) | for(I + 1, Max, F)].

qsort([]) -> [];
qsort([Pivot|T]) ->
  qsort([X || X <- T, X < Pivot])
  ++ [Pivot] ++
  qsort([X || X <- T, X >= Pivot]).

pythag(N) ->
  [{A,B,C} || A <- lists:seq(1,N), B <- lists:seq(1,N), C <- lists:seq(1,N),
              A+B+C =< N, A*A + B*B =:= C*C].

perms([]) -> [[]];
perms(L) -> [[H|T] || H <- L, T <- perms(L -- [H])].

odds_and_evens1(L) ->
  Odds = [X || X <- L, (X rem 2) =:= 1],
  Evens = [X || X <- L, (X rem 2) =:= 0],
  {Odds, Evens}.

odds_and_evens2(L) ->
  odds_and_evens_acc(L, [],[]).
odds_and_evens_acc([H|T], Odds, Evens)->
  case (H rem 2) of
    1 -> odds_and_evens_acc(T, [H | Odds], Evens);
    0 -> odds_and_evens_acc(T, Odds, [H | Evens])
  end;
odds_and_evens_acc([], Odds, Evens) ->
  {lists:reverse(Odds), lists:reverse(Evens)}.

my_tuple_to_lists(T) -> my_tuple_to_lists_acc(tuple_size(T), T, []).

my_tuple_to_lists_acc(0, _, L) -> L;
my_tuple_to_lists_acc(N, T, L) ->
  my_tuple_to_lists_acc(N - 1, T, [element(N,T) | L]).

my_tuple_to_list(T) -> my_tuple_to_lists_acc(tuple_size(T), T, []).

priority_receive() ->
  receive
    {alarm, X} ->
      {alarm, X}
  after 0 ->
          receive
            Any -> Any
          end
  end.

on_exit(Pid, Fun) ->
  spawn(fun() ->
            Ref = monitor(process, Pid),
            receive
              {'DOWN', Ref, process, Pid, Why} ->
                Fun(Why)
            end
        end).
even(A) -> case A rem 2 of
             0 -> true;
             1 -> false
           end.
odd(A) -> even(A + 1).

my_time_func(F) -> io:format("~w~p",[date()]),
                   F(),
                   io:format("~w~p", [date()]).
